﻿using System;
using System.Text;
using AchSegítő.extensions;
using AchSegítő.utils;

namespace AchSegítő.File
{
    /// <summary>
    /// What is the RDFI, receiver, and amount?
    /// </summary>
    public class EntryDetail
    {
        #region Private

        #endregion
        public readonly RecordTypeCodes RecordTypeCode = RecordTypeCodes.EntryDetail;

        /// <summary>
        /// THE TRANSACTION CODE IDENTIFIES THE TYPE OF ENTRY.
        /// </summary>
        public TransactionCode TransactionCode = TransactionCode.CheckingCredit;

        /// <summary>
        /// FIRST 8 DIGITS OF THE RECEIVER’S BANK TRANSIT ROUTING NUMBER AT
        /// THE FINANCIAL INSTITUTION WHERE THE RECEIVER'S ACCOUNT IS MAINTAINED.
        /// </summary>
        public String ReceivingDFIIdentification { get; set; } = String.Empty;

        /// <summary>
        /// LAST DIGIT OF RECEIVER'S BANK TRANSIT ROUTING NUMBER.
        /// </summary>
        public char CheckDigit { get; set; }

        /// <summary>
        /// THIS IS THE RECEIVER’S BANK ACCOUNT NUMBER. IF THE ACCOUNT NUMBER
        /// EXCEEDS 17 POSITIONS, ONLY USE THE LEFT MOST 17 CHARACTERS. ANY
        /// SPACES WITHIN THE ACCOUNT NUMBER SHOULD BE OMITTED WHEN PREPARING
        /// THE ENTRY. THIS FIELD MUST BE LEFT JUSTIFIED.
        /// </summary>
        public String DFIAccountNumber { get; set; } = String.Empty;

        /// <summary>
        /// The amount of the transaction in decimal format. Will be converted when writing the file.
        /// </summary>
        public Decimal Amount { get; set; } = decimal.Zero;

        /// <summary>
        /// THIS IS AN IDENTIFYING NUMBER BY WHICH THE RECEIVER IS KNOWN TO
        /// THE ORIGINATOR. IT IS INCLUDED FOR FURTHER IDENTIFICATION AND
        /// DESCRIPTIVE PURPOSES.
        /// </summary>
        public String IndividualIdentificationNumber { get; set; } = String.Empty;

        /// <summary>
        /// THIS IS THE NAME IDENTIFYING THE RECEIVER OF THE TRANSACTION.
        /// </summary>
        public String IndividualName { get; set; } = String.Empty;

        /// <summary>
        /// THIS FIELD MUST BE LEFT BLANK.
        /// </summary>
        public String DiscretionaryData { get; set; } = String.Empty;

        /// <summary>
        /// IF PPD OR CCD, ENTER 0 IN THIS FIELD TO INDICATE NO ADDENDA
        /// RECORD WILL FOLLOW. IF AN ADDENDA DOES FOLLOW THIS DETAIL RECORD,
        /// ENTER 1 TO INDICATE A '7' RECORD WILL FOLLOW.
        /// </summary>
        public readonly int AddendaRecordIndicator = 0;

        /// <summary>
        /// THE TRACE NUMBER IS A MEANS FOR THE
        /// ORIGINATOR TO IDENTIFY THE INDIVIDUAL ENTRIES.THE FIRST 8 POSITIONS
        /// OF THE FIELD SHOULD BE YOUR PNC BANK TRANSIT ROUTING NUMBER (WITHOUT THE
        /// CHECK DIGIT). THE REMAINDER OF THE FIELD MUST BE A UNIQUE NUMBER,
        /// ASSIGNED IN ASCENDING ORDER FOR EACH ENTRY.TRACE NUMBERS MAY BE
        /// DUPLICATED ACROSS DIFFERENT FILES.
        /// </summary>
        public String TraceNumber { get; set; } = String.Empty;

// Routing # + company record count

        public override string ToString()
        {
            var sb = new StringBuilder(ACH.CHARACTERS_PER_LINE);

            sb.Append((int)RecordTypeCode);

            sb.Append((int)TransactionCode);

            sb.Append(ReceivingDFIIdentification.TrimAndPadRight(8));

            sb.Append(CheckDigit);

            sb.Append(DFIAccountNumber.TrimAndPadRight(17));

            sb.Append((Amount * 100).ToString("0").TrimAndPadLeft(10, '0')); // 123.45 => 0000012345

            sb.Append(IndividualIdentificationNumber.TrimAndPadRight(15));

            sb.Append(IndividualName.TrimAndPadRight(22));

            sb.Append(DiscretionaryData.TrimAndPadRight(2));

            sb.Append(AddendaRecordIndicator.ToString().TrimAndPadLeft(1, '0'));

            sb.Append(TraceNumber.ToString().TrimAndPadLeft(15, '0'));

            sb.AppendLine();

            return sb.ToString();
        }
    }
}